-
Notifications
You must be signed in to change notification settings - Fork 710
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
JSON Serialization Improvements #936
Conversation
Also update tests to correctly use the serializer - it wasn't tested before.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for cleaning out the duplicated code. I would like to see if we can simplify this.
src/lib/serialization/schema.ts
Outdated
* | ||
* For documentation on the JSON output properties, view the corresponding model. | ||
*/ | ||
export namespace JSONOutput { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the motivation to have this as a namespace? Should we have a top level model exporting these (i.e. typedoc/serialization
)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe my idea was to avoid polluting the global scope with ~40 new types.
The new top level export makes sense, but I think the way to do it should probably be to not publish TypeDoc within the dist/lib
folder, this would be a massive breaking change, since basically all plugins import the Component
decorator from typedoc/dist/lib/...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've moved these out of the namespace, there was no need as avoiding the pollution could be done by re-exporting under a specific name later. I still think the typedoc/serialization
module is a good idea, but again, breaking changes that don't need to happen yet & should be thought through carefully.
src/lib/serialization/schema.ts
Outdated
*/ | ||
export type ModelToObject<T> = T extends Array<infer U> ? _ModelToObject<U>[] : _ModelToObject<T>; | ||
|
||
// Order matters here. Some types are subtypes of other types. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's an important note. Thanks for calling it out.
I was hoping that we could have some type of keyof
mapping that might be simpler but it doesn't sound like that's possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With some changes to the JSON output, it would be possible, but for the initial typing I decided to just maintain the existing output types.
* Return a raw object representation of this reflection. | ||
* @deprecated Use serializers instead | ||
*/ | ||
toObject(): any { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to stub this with a call to the real serializer? This would help those who are looking for the serializer on the ProjectReflection.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is possible, yes, but I'm not sure it is a good idea. To make it work we have 2 options.
- Construct a new serializer whenever
.toObject
is called - Add an
application: Application
property to every reflection so that it can access the real serializer.
There are problems with both.
- The new serializer will be missing any extra serializers added by plugins
- Requires changing every reflection, and reflections really shouldn't know about serializers anyways (at least, that's the theory with having separate serialization...)
Since .toObject
has been deprecated for nearly 2 years, I feel pretty ok about just removing the method.
src/lib/serialization/schema.ts
Outdated
title: M.ReflectionGroup['title']; | ||
kind: M.ReflectionGroup['kind']; | ||
children?: M.ReflectionGroup['children'][number]['id'][]; | ||
categories?: ModelToObject<M.ReflectionGroup['categories']>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it make sense to move these interfaces to the individual serializers?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it absolutely makes sense 👍 Will do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Coming back to this, I'm not sure it does make sense. It's still an option, but having all the types in one place lets us avoid importing the S
helper I introduced to resolve another of your comments everywhere (and thus keeps that particular bit of ugly out of the rest of of the code)
On the other hand, it would be nice to have the types closer to the code that produces values of that type...
src/lib/serialization/schema.ts
Outdated
type?: ModelToObject<M.SignatureReflection['implementationOf']>; | ||
overwrites?: ModelToObject<M.SignatureReflection['implementationOf']>; | ||
inheritedFrom?: ModelToObject<M.SignatureReflection['implementationOf']>; | ||
implementationOf?: ModelToObject<M.SignatureReflection['implementationOf']>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Many of these look like they could be simplified using a keyof
mapping.
Something like
type SignatureReflection = SimpleSerialization<Reflection>
This would help avoid issues when refactoring property names.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How did I miss the names here... I was avoiding keyof
since for some reflections, not all properties are exported (notably, parent
is absent as JSON can't include circular data structures)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, while it is certainly possible to use Exclude
on the keyof
result, this results in types which are displayed in a much less user friendly manner. The redundancy hurts, but I think it is probably worth it for types that can be easily explored.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we have common patterns (like parent
) there should be a way to exclude that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I gave this a shot, looking into preventing specific properties from being serialized and I don't think it is the right way to go about this.
- The list changes for (almost) every serialized reflection.
- As soon as a new property is added to a reflection, the serializer types have to be updated, even though nothing changed there.
Instead I introduced a helper S
local to this file that handles basic cases. It behaves similarly to Pick
, but passes properties through ModelToObject
if necessary. Thoughts?
…ix/serializer-plugin
It did nothing more than Assert.deepStrictEqual, since if the objects weren't exactly the same deepEqual would throw.
- Move JSON types out of the namespace - Introduce a helper to semi-automatically conver types to their JSON equivalent - Address all the build errors caused by removing the namespace
This is a rework of the JSON serialization, completing the work done in #597 and removing the deprecated
.toObject
methods.The JSON schema retains the old structure, which is now described by the
JSONOutput
namespace.closes #930
closes #728
closes #605